package soria.cabinet.gui.components.encrypt;

import soria.cabinet.security.Device;
import soria.cabinet.security.Pattern;
import soria.cabinet.utils.EncryptComponents;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.*;

public class OperatePosition {
    //Panel
    public static JPanel panel = new JPanel();
    // 创建一个label，并设置文本为“操作”
    private static final JLabel operateLabel = EncryptComponents.createLabel("操作");
    // 创建一个button，并设置文本为“选择待加密文件”，设置y位置为70
    private static final JButton selectEncryptBtn = EncryptComponents.createBtn("选择待加密文件", 70);
    // 创建一个button，并设置文本为“选择待解密文件”，设置y位置为140
    private static final JButton selectDecryptBtn = EncryptComponents.createBtn("选择待解密文件", 140);
    // 创建一个button，并设置文本为“移除选中文件”，设置y位置为210
    private static final JButton deleteBtn = EncryptComponents.createBtn("移除选中文件", 210);
    // 创建一个button，并设置文本为“加密文件”，设置y位置为280
    private static final JButton encryptBtn = EncryptComponents.createBtn("加密文件", 280);
    // 创建一个button，并设置文本为“解密文件”，设置y位置为350
    private static final JButton decryptBtn = EncryptComponents.createBtn("解密文件", 350);
    //加密文件GUI列表
    private static final DefaultListModel<String> encryptListModel = new DefaultListModel<>();
    //解密文件GUI列表
    private static final DefaultListModel<String> decryptListModel = new DefaultListModel<>();
    //加密文件列表
    private static final Map<String, File> encryptMap = new HashMap<>();
    //解密文件列表
    private static final Map<String, File> decryptMap = new HashMap<>();

    static {
        EncryptComponents.initialPanel(panel);
        panel.setBounds(610, 5, 220, 517);
        initial();
    }

    private static void initial() {
        operateLabel.setBounds(90, 10, 100, 30);
        panel.add(operateLabel);

        selectEncryptBtn.addActionListener(new SelectListener());
        panel.add(selectEncryptBtn);

        selectDecryptBtn.addActionListener(new SelectListener());
        panel.add(selectDecryptBtn);

        deleteBtn.addActionListener(new DeleteListener());
        panel.add(deleteBtn);

        encryptBtn.addActionListener(new EncryptListener());
        panel.add(encryptBtn);

        decryptBtn.addActionListener(new DecryptListener());
        panel.add(decryptBtn);
    }

    //事件监听器：选择待加密文件和待解密文件
    private static class SelectListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // 选择文件
            JFileChooser jfc = new JFileChooser();
            jfc.setCurrentDirectory(new File(new File("").getAbsolutePath()+"/Cabinet"));
            //设置只能选择文件
            jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            //设置允许多选
            jfc.setMultiSelectionEnabled(true);
            jfc.setDialogTitle("请选择文件");
            jfc.showDialog(null, "选择");

            JButton button = (JButton) e.getSource();
            File[] files = jfc.getSelectedFiles();
            //添加需要加密或解密的文件到Map
            for (File file : files) {
                if (button.getText().equals("选择待加密文件")){
                    add(encryptListModel, encryptMap,file);
                }else {
                    add(decryptListModel, decryptMap,file);
                }
            }
            //显示到JList
            if (((JButton) e.getSource()).getText().equals("选择待加密文件")) {
                FileSelectionPosition.encryptList.setModel(encryptListModel);
            } else {
                FileSelectionPosition.decryptList.setModel(decryptListModel);
            }
        }

        /**
         * 添加选择的文件到列表
         * @param listModel 关联GUI列表的DefaultListModel
         * @param map 文件列表
         * @param file 待添加的文件
         */
        private void add(DefaultListModel<String> listModel, Map<String, File> map, File file) {
            if (!listModel.contains(file.getName())) {
                listModel.addElement(file.getName());
                map.put(file.getName(), file);
            }
        }
    }

    //事件监听器：删除待加密文件或待解密文件中所选中的项
    private static class DeleteListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            //移除待加密文件和待解密文件列表中的选项
            JList<String> encryptList = FileSelectionPosition.encryptList;
            JList<String> decryptList = FileSelectionPosition.decryptList;
            remove(encryptList, encryptMap);
            remove(decryptList, decryptMap);
        }

        /**
         * 移除文件列表中的项
         *
         * @param list GUI窗口中的列表
         * @param map  后台存储的列表
         */
        private void remove(JList<String> list, Map<String, File> map) {
            DefaultListModel<String> model = (DefaultListModel<String>) list.getModel();
            int[] selectedIndices = list.getSelectedIndices();
            int len = selectedIndices.length;
            for (int i = 0; i < len; i++) {
                map.remove(model.get(selectedIndices[i]));
            }
            for (int i = 0; i < len; len--) {
                model.remove(selectedIndices[i]);
            }
            list.setModel(model);
        }
    }

    //事件监听器:对文件进行加密
    private static class EncryptListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // 加密文件
            for(Map.Entry<String,File> entry:encryptMap.entrySet()){
                File encryptFile = entry.getValue();
                Device.fileHandle(encryptFile, Pattern.ENCRYPT);
            }
            JOptionPane.showMessageDialog(encryptBtn,"加密成功！");
            FileSelectionPosition.encryptList.setListData(new String[0]);
            encryptListModel.clear();
            encryptMap.clear();
        }
    }

    //事件监听器：对文件进行解密
    private static class DecryptListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // 解密文件
            String key = FileSelectionPosition.secretKeyText.getText().trim();
            if(key.isEmpty()){
                JOptionPane.showMessageDialog(decryptBtn, "请输入密钥！");
                return;
            }
            String secretKey = Device.decryptKey(key);
            if (secretKey != null && secretKey.length() != 16) {
                JOptionPane.showMessageDialog(decryptBtn, "密钥不正确！");
            }else {
                for(Map.Entry<String,File> entry:decryptMap.entrySet()){
                    File decryptFile = entry.getValue();
                    Device.fileHandle(decryptFile, Pattern.DECRYPT,secretKey);
                }
                JOptionPane.showMessageDialog(decryptBtn, "解密成功！");
                FileSelectionPosition.decryptList.setListData(new String[0]);
                decryptListModel.clear();
                decryptMap.clear();
            }
        }
    }
}
